-
Notifications
You must be signed in to change notification settings - Fork 190
feat: add conversations_unreads and conversations_mark tools #146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: add conversations_unreads and conversations_mark tools #146
Conversation
…rieval - Uses ClientUserBoot to get all channels with LastRead/Latest in one API call - Filters channels where Latest > LastRead to find unreads - Prioritizes: DMs > group DMs > partner channels (ext-*) > internal - Only fetches message history for channels with actual unreads - Supports filtering by channel type and configurable limits Addresses issue korotovsky#114
- Switch from ClientUserBoot to ClientCounts API - ClientCounts returns HasUnreads boolean for all channels - Add ClientCounts to SlackAPI interface - Process Channels, MPIMs, and IMs separately
- Strip existing # prefix before adding to avoid ##name - Use stripped name for ext-/shared- prefix checks for partner type
- Add mentions_only parameter to conversations_unreads to filter channels to only those with @mentions (priority inbox) - Add conversations_mark tool to mark channels/DMs as read - Supports channel IDs, #channel names, and @username - If no timestamp provided, marks all messages as read
…nels - Add IsExtShared field to Channel struct in cache - Pass IsExtShared through mapChannel function - Use cached.IsExtShared to identify external/partner channels instead of checking for ext-/shared- name prefixes Note: Users may need to delete their channels cache file to repopulate with the new IsExtShared field.
korotovsky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @saoudrizwan, thank you for the great contribution!
Since the new API method has been introduced and this MCP supports multiple slack token types, a question from my side: have you checked that ClientCounts also returns data if we provide xoxb or xoxp (as I assume your main setup is xoxc/xoxd pair since you are using undocumented APIs, this is is where this API works the best and has the most coverage)
|
Hi @saoudrizwan, would you like to finalize the PR or we must to find someone within the community to pick it up? |
- Extract handler params to structs with parsing functions (unreadsParams, markParams) following existing patterns - Add SLACK_MCP_MARK_TOOL env var guard for conversations_mark (disabled by default, requires explicit opt-in) - Remove unused categorizeChannel and getChannelDisplayName functions - Update README with conversations_mark safety note and env var docs
|
Hey @korotovsky, thanks for the review! I've addressed all the inline comments in 4ffa603:
Regarding token compatibility: you're right that I've been testing with Looking at the edge client implementation,
If you'd like, I can add a note in the README that |
|
Hi @saoudrizwan, thanks for fixes. As of regarding token types, would be ideal if you could manually test |
…mark tools Adds: - conversations_unreads: Get unread messages across all channels efficiently - Priority sorting: DMs > partner channels > internal - Supports @mention filtering, channel type filtering - conversations_mark: Mark channels as read (disabled by default for safety) - IsExtShared field for partner channel detection - ClientCounts edge API method Note: Binary file (build/slack-mcp-server) excluded from merge for security. Original PR: korotovsky#146
Adds two new tools for efficiently managing unread Slack messages 🚀
When you're in a lot of Slack channels (especially with external partner channels), keeping up with unreads becomes overwhelming. The existing
conversations_historytool requires you to know which channel to check. These new tools let you:New Tools
conversations_unreadsEfficiently retrieves unread messages across all channels using a single API call.
Parameters:
include_messagestruechannel_types"all""dm","group_dm","partner","internal", or"all"max_channels50max_messages_per_channel10mentions_onlyfalseOutput (CSV):
conversations_markMarks a channel or DM as read.
Parameters:
channel_id#channel-name, or@usernametsTechnical Implementation
Why
client.countsAPI?We initially tried using
ClientUserBootbut discovered it only returns channels in the user's sidebar, not all channels with unreads. Theclient.countsAPI (already implemented in the edge client) is what Slack's web client uses:HasUnreadsboolean andMentionCountfor ALL channels in one callChannels,MPIMs(group DMs),IMs(direct messages)Channel Categorization & Priority
Results are automatically sorted by priority:
dm) - Direct messages, highest prioritygroup_dm) - Multi-person direct messagespartner) - Externally shared channels (usesIsExtSharedmetadata)internal) - Everything elseCode Changes
pkg/provider/api.goIsExtSharedfield toChannelstructClientCountsmethod onSlackAPIinterfacemapChannelto pass throughIsExtSharedpkg/handler/conversations.goUnreadChannelstruct for CSV outputConversationsUnreadsHandlerwith priority sorting and filteringConversationsMarkHandlerwith channel name resolutionsortChannelsByPriorityhelperpkg/server/server.goExample Use Cases
1. Morning Inbox Review
2. Priority Inbox - Just @Mentions
3. Check Partner Channels Only
4. Quick Summary Without Messages
5. Mark Channel as Read
6. Triage Workflow
Breaking Changes
Users with existing channel caches will need to delete
~/Library/Caches/slack-mcp-server/channels_cache_v2.json(or equivalent) to repopulate with the newIsExtSharedfield. Otherwise, partner channel detection won't work until the cache is refreshed.Test Plan
conversations_unreadsreturns prioritized list of unread channelschannel_typesfilter correctly filters by dm/group_dm/partner/internalmentions_only: truefilters to only channels with @mentionsinclude_messages: falsereturns summary without fetching message contentIsExtSharedmetadata (not name prefix)conversations_markmarks channels as read using channel IDconversations_markresolves#channel-nameto channel IDconversations_markresolves@usernameto DM channel IDconversations_markwithout timestamp marks all messages as read